package ar.edu.uba.fi.jmit.aspecter.monitor.fieldValue;

import java.util.Date;
import java.util.List;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import ar.edu.uba.fi.jmit.aspecter.AspecterTestCase;
import ar.edu.uba.fi.jmit.aspecter.core.Constants;
import ar.edu.uba.fi.jmit.aspecter.core.ResourceProperties;
import ar.edu.uba.fi.jmit.aspecter.core.WeavingInstrumentor;
import ar.edu.uba.fi.jmit.aspecter.core.WeavingInstrumentorFactory;
import ar.edu.uba.fi.jmit.aspecter.monitor.testUtils.EventPriorityMock;
import ar.edu.uba.fi.jmit.aspecter.monitor.testUtils.MockEvent;
import ar.edu.uba.fi.jmit.aspecter.monitor.testUtils.SenderFactoryMock;

public class FieldValueInstrumentorTestCase extends AspecterTestCase {

	public void test() throws NotFoundException {
		SenderFactoryMock.clean();
		String className = getNextClassName();
		try {
			WeavingInstrumentor instrumentor = WeavingInstrumentorFactory.getInstance().getFieldValueMethodInstrumentor("FieldValueInstrumentorTestCase.test", className, "timetaken", "getId()", "ALERT");
			CtClass ctClazz = ClassPool.getDefault().getAndRename("ar.edu.uba.fi.jmit.aspecter.monitor.testUtils.MonitorTarget", className);
			instrumentor.alter(ctClazz);
			Class<?> clazz = ctClazz.toClass();
			assertEquals(0, SenderFactoryMock.getSenderInstance().getHpSendedEvents().size());
			Object object = clazz.newInstance();
			assertEquals(1, SenderFactoryMock.getSenderInstance().getHpSendedEvents().size());
			assertEquals(0L, SenderFactoryMock.getSenderInstance().getHpSendedEvents().get(0).getData().get(ResourceProperties.getProperty(Constants.FIELD_NEW_VALUE)));
			clazz.getMethod("setId", int.class).invoke(object, 10);
			clazz.getMethod("methodTime").invoke(object);
			List<MockEvent> list = SenderFactoryMock.getSenderInstance().getHpSendedEvents();
			assertEquals(2, list.size());
			MockEvent secondEvent = list.get(1);
			assertEquals(10, secondEvent.getData().get(ResourceProperties.getProperty(Constants.EVENT_ID_OBJECT_KEY)));
			assertEquals("FieldValueInstrumentorTestCase.test", secondEvent.getData().get(ResourceProperties.getProperty(Constants.EVENT_MONITOR_NAME_KEY)));
			assertSimilarDates(new Date(), (Date) secondEvent.getData().get(ResourceProperties.getProperty(Constants.EVENT_MONITOR_DATE)));
			assertEquals(object.toString(), secondEvent.getSource());
			assertEquals(EventPriorityMock.ALERT, secondEvent.getPriority());
			assertEquals(clazz.getMethod("getTimetaken").invoke(object), secondEvent.getData().get(ResourceProperties.getProperty(Constants.FIELD_NEW_VALUE)));
			assertEquals(0, SenderFactoryMock.getSenderInstance().getSendedEvents().size());
		} catch (Exception e) {
			fail(e);
		}
	}
}
